package com.ken.astroboy.quartz;

import java.util.Date;

import org.quartz.CronScheduleBuilder;
  
import org.quartz.CronTrigger;
import org.quartz.Job;
import org.quartz.JobBuilder;
import org.quartz.JobDetail;
import org.quartz.JobKey;
import org.quartz.Scheduler;
import org.quartz.SchedulerException;
import org.quartz.SchedulerFactory;
import org.quartz.TriggerBuilder;
import org.quartz.TriggerKey;
import org.quartz.impl.StdSchedulerFactory;
import org.quartz.impl.triggers.CronTriggerImpl;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import com.ken.astroboy.model.ScheduledTaskItem;
import com.ken.astroboy.util.Exceptions;
  
 
public class QuartzManager {
	
	private final static Logger logger = LoggerFactory.getLogger(QuartzManager.class);
	    
    private final static String JOB_GROUP_NAME = "ATM_JOB_GROUP_NAME";  
    private final static String TRIGGER_GROUP_NAME = "ATM_TRIGGER_GROUP_NAME";  
  
    private static Scheduler sched = getSchedulerInstance();  
 
    private static Scheduler getSchedulerInstance() {  
            SchedulerFactory sf = new StdSchedulerFactory();  
            Scheduler scheduler=null;  
            try {  
                scheduler = sf.getScheduler();  
            } catch (SchedulerException e) {  
    			logger.info(Exceptions.getExceptionDetail(e));
            }  
            return scheduler;  
    } 
    
    public static Scheduler getScheduler(){  
        return sched;  
    } 
    
    @SuppressWarnings("unchecked")
	public static boolean addJob(String jobName, ScheduledTaskItem taskItem) {  
        try {              
        	Class<? extends Job> jobClass = (Class<? extends Job>) Class.forName(taskItem.getJobClassName());
        	
            JobDetail jobDetail = JobBuilder.newJob(jobClass)
            					  .withIdentity(jobName, JOB_GROUP_NAME)
            					  .build();
  		
            jobDetail.getJobDataMap().put(jobName, taskItem.getCustomData());
    		
            CronTrigger trigger = TriggerBuilder.newTrigger()
				    			  .withIdentity(jobName, TRIGGER_GROUP_NAME)
				    			  .withSchedule(CronScheduleBuilder.cronSchedule(taskItem.getScheduledTime()))
				    			  .build();	
            
            sched.scheduleJob(jobDetail, trigger);            
            
            return true;
            
        } catch (Exception e) {
			logger.info(Exceptions.getExceptionDetail(e));
        	return false;
        }  
    }  
  
    
    public static boolean modifyJob(String jobName, ScheduledTaskItem taskItem) {  
    	if(removeJob(jobName)){
    		return addJob(jobName, taskItem);      
        }
		return false;  
    }   
  

    public static boolean removeJob(String jobName) {  
        try {                          
            sched.pauseTrigger( new TriggerKey(jobName, TRIGGER_GROUP_NAME) );// 停止触发器  
            sched.unscheduleJob( new TriggerKey(jobName, TRIGGER_GROUP_NAME) );// 移除触发器  
            sched.deleteJob( new JobKey(jobName, JOB_GROUP_NAME) );// 删除任务  
            return true;
            
        } catch (Exception e) {  
			logger.info(Exceptions.getExceptionDetail(e));
        	return false;
        }  
    }  

  
    public static boolean startScheduler() {  
    	
        try {              
            sched.start();        
        } catch (Exception e) {  
			logger.info(Exceptions.getExceptionDetail(e));
        	return false;
        }
        
        return true;
    }  
  
    public static boolean standbyScheduler() {  
        try {  
            sched.standby();
        } catch (Exception e) {  
			logger.info(Exceptions.getExceptionDetail(e));
        	return false;
        } 
        return true;
    }
    
    public static void shutdownScheduler() {  
        try {  
        	sched.shutdown();  
        } catch (Exception e) {  
            throw new RuntimeException(e);  
        }  
    }
    
    
    public static boolean pauseJob(String jobName) {  
        try {  
            sched.pauseTrigger(new TriggerKey(jobName, TRIGGER_GROUP_NAME));
            return true;
        } catch (Exception e) {  
			logger.info(Exceptions.getExceptionDetail(e));
        	return false;
        }  
    }  
    
    public static boolean resumeJob(String jobName) {
        try {  
            
            TriggerKey triggerKey = new TriggerKey(jobName, TRIGGER_GROUP_NAME); 
            
            CronTrigger trigger = (CronTrigger) sched.getTrigger(triggerKey);
            ((CronTriggerImpl)trigger).setStartTime(new Date());
            
            sched.rescheduleJob(triggerKey, trigger);
            
            return true;
        } catch (Exception e) {  
			logger.info(Exceptions.getExceptionDetail(e));
        	return false;
        }  
    } 
}  